f152146965129e1ff017bb89be52fbe3754f98d8
[lhc/web/wiklou.git] / languages / Language.php
1 <?php
2 /**
3 * @package MediaWiki
4 * @subpackage Language
5 */
6
7 if( defined( 'MEDIAWIKI' ) ) {
8
9 #
10 # In general you should not make customizations in these language files
11 # directly, but should use the MediaWiki: special namespace to customize
12 # user interface messages through the wiki.
13 # See http://meta.wikipedia.org/wiki/MediaWiki_namespace
14 #
15 # NOTE TO TRANSLATORS: Do not copy this whole file when making translations!
16 # A lot of common constants and a base class with inheritable methods are
17 # defined here, which should not be redefined. See the other LanguageXx.php
18 # files for examples.
19 #
20
21 #--------------------------------------------------------------------------
22 # Language-specific text
23 #--------------------------------------------------------------------------
24
25 if($wgMetaNamespace === FALSE)
26 $wgMetaNamespace = str_replace( ' ', '_', $wgSitename );
27
28 /* private */ $wgNamespaceNamesEn = array(
29 NS_MEDIA => 'Media',
30 NS_SPECIAL => 'Special',
31 NS_MAIN => '',
32 NS_TALK => 'Talk',
33 NS_USER => 'User',
34 NS_USER_TALK => 'User_talk',
35 NS_PROJECT => $wgMetaNamespace,
36 NS_PROJECT_TALK => $wgMetaNamespace . '_talk',
37 NS_IMAGE => 'Image',
38 NS_IMAGE_TALK => 'Image_talk',
39 NS_MEDIAWIKI => 'MediaWiki',
40 NS_MEDIAWIKI_TALK => 'MediaWiki_talk',
41 NS_TEMPLATE => 'Template',
42 NS_TEMPLATE_TALK => 'Template_talk',
43 NS_HELP => 'Help',
44 NS_HELP_TALK => 'Help_talk',
45 NS_CATEGORY => 'Category',
46 NS_CATEGORY_TALK => 'Category_talk',
47 );
48
49 if(isset($wgExtraNamespaces)) {
50 $wgNamespaceNamesEn=$wgNamespaceNamesEn+$wgExtraNamespaces;
51 }
52
53 /* private */ $wgDefaultUserOptionsEn = array(
54 'quickbar' => 1,
55 'underline' => 2,
56 'cols' => 80,
57 'rows' => 25,
58 'searchlimit' => 20,
59 'contextlines' => 5,
60 'contextchars' => 50,
61 'skin' => $wgDefaultSkin,
62 'math' => 1,
63 'rcdays' => 7,
64 'rclimit' => 50,
65 'highlightbroken' => 1,
66 'stubthreshold' => 0,
67 'previewontop' => 1,
68 'editsection' => 1,
69 'editsectiononrightclick'=> 0,
70 'showtoc' => 1,
71 'showtoolbar' => 1,
72 'date' => 0,
73 'imagesize' => 2,
74 'thumbsize' => 2,
75 'rememberpassword' => 0,
76 'enotifwatchlistpages' => 0,
77 'enotifusertalkpages' => 1,
78 'enotifminoredits' => 0,
79 'enotifrevealaddr' => 0,
80 'shownumberswatching' => 1,
81 'fancysig' => 0,
82 'externaleditor' => 0,
83 'externaldiff' => 0,
84 'showjumplinks' => 1,
85 'numberheadings' => 0,
86 'uselivepreview' => 0,
87 );
88
89 /* private */ $wgQuickbarSettingsEn = array(
90 'None', 'Fixed left', 'Fixed right', 'Floating left', 'Floating right'
91 );
92
93 /* private */ $wgSkinNamesEn = array(
94 'standard' => 'Classic',
95 'nostalgia' => 'Nostalgia',
96 'cologneblue' => 'Cologne Blue',
97 'davinci' => 'DaVinci',
98 'mono' => 'Mono',
99 'monobook' => 'MonoBook',
100 'myskin' => 'MySkin',
101 'chick' => 'Chick'
102 );
103
104 /* private */ $wgMathNamesEn = array(
105 MW_MATH_PNG => 'mw_math_png',
106 MW_MATH_SIMPLE => 'mw_math_simple',
107 MW_MATH_HTML => 'mw_math_html',
108 MW_MATH_SOURCE => 'mw_math_source',
109 MW_MATH_MODERN => 'mw_math_modern',
110 MW_MATH_MATHML => 'mw_math_mathml'
111 );
112
113 /**
114 * Whether to use user or default setting in Language::date()
115 *
116 * NOTE: the array string values are no longer important!
117 * The actual date format functions are now called for the selection in
118 * Special:Preferences, and the 'datedefault' message for MW_DATE_DEFAULT.
119 *
120 * The array keys make up the set of formats which this language allows
121 * the user to select. It's exposed via Language::getDateFormats().
122 *
123 * @access private
124 */
125 $wgDateFormatsEn = array(
126 MW_DATE_DEFAULT => 'No preference',
127 MW_DATE_DMY => '16:12, 15 January 2001',
128 MW_DATE_MDY => '16:12, January 15, 2001',
129 MW_DATE_YMD => '16:12, 2001 January 15',
130 MW_DATE_ISO => '2001-01-15 16:12:34'
131 );
132
133 /* private */ $wgUserTogglesEn = array(
134 'highlightbroken',
135 'justify',
136 'hideminor',
137 'usenewrc',
138 'numberheadings',
139 'showtoolbar',
140 'editondblclick',
141 'editsection',
142 'editsectiononrightclick',
143 'showtoc',
144 'rememberpassword',
145 'editwidth',
146 'watchdefault',
147 'minordefault',
148 'previewontop',
149 'previewonfirst',
150 'nocache',
151 'enotifwatchlistpages',
152 'enotifusertalkpages',
153 'enotifminoredits',
154 'enotifrevealaddr',
155 'shownumberswatching',
156 'fancysig',
157 'externaleditor',
158 'externaldiff',
159 'showjumplinks',
160 'uselivepreview',
161 );
162
163 /* private */ $wgBookstoreListEn = array(
164 'AddALL' => 'http://www.addall.com/New/Partner.cgi?query=$1&type=ISBN',
165 'PriceSCAN' => 'http://www.pricescan.com/books/bookDetail.asp?isbn=$1',
166 'Barnes & Noble' => 'http://search.barnesandnoble.com/bookSearch/isbnInquiry.asp?isbn=$1',
167 'Amazon.com' => 'http://www.amazon.com/exec/obidos/ISBN=$1'
168 );
169
170 # Read language names
171 global $wgLanguageNames;
172 /** */
173 require_once( 'Names.php' );
174
175 $wgLanguageNamesEn =& $wgLanguageNames;
176
177
178 /* private */ $wgWeekdayNamesEn = array(
179 'sunday', 'monday', 'tuesday', 'wednesday', 'thursday',
180 'friday', 'saturday'
181 );
182
183
184 /* private */ $wgMonthNamesEn = array(
185 'january', 'february', 'march', 'april', 'may_long', 'june',
186 'july', 'august', 'september', 'october', 'november',
187 'december'
188 );
189 /* private */ $wgMonthNamesGenEn = array(
190 'january-gen', 'february-gen', 'march-gen', 'april-gen', 'may-gen', 'june-gen',
191 'july-gen', 'august-gen', 'september-gen', 'october-gen', 'november-gen',
192 'december-gen'
193 );
194
195 /* private */ $wgMonthAbbreviationsEn = array(
196 'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug',
197 'sep', 'oct', 'nov', 'dec'
198 );
199
200 # Note to translators:
201 # Please include the English words as synonyms. This allows people
202 # from other wikis to contribute more easily.
203 #
204 /* private */ $wgMagicWordsEn = array(
205 # ID CASE SYNONYMS
206 MAG_REDIRECT => array( 0, '#REDIRECT' ),
207 MAG_NOTOC => array( 0, '__NOTOC__' ),
208 MAG_FORCETOC => array( 0, '__FORCETOC__' ),
209 MAG_TOC => array( 0, '__TOC__' ),
210 MAG_NOEDITSECTION => array( 0, '__NOEDITSECTION__' ),
211 MAG_START => array( 0, '__START__' ),
212 MAG_CURRENTMONTH => array( 1, 'CURRENTMONTH' ),
213 MAG_CURRENTMONTHNAME => array( 1, 'CURRENTMONTHNAME' ),
214 MAG_CURRENTMONTHNAMEGEN => array( 1, 'CURRENTMONTHNAMEGEN' ),
215 MAG_CURRENTMONTHABBREV => array( 1, 'CURRENTMONTHABBREV' ),
216 MAG_CURRENTDAY => array( 1, 'CURRENTDAY' ),
217 MAG_CURRENTDAY2 => array( 1, 'CURRENTDAY2' ),
218 MAG_CURRENTDAYNAME => array( 1, 'CURRENTDAYNAME' ),
219 MAG_CURRENTYEAR => array( 1, 'CURRENTYEAR' ),
220 MAG_CURRENTTIME => array( 1, 'CURRENTTIME' ),
221 MAG_NUMBEROFARTICLES => array( 1, 'NUMBEROFARTICLES' ),
222 MAG_NUMBEROFFILES => array( 1, 'NUMBEROFFILES' ),
223 MAG_PAGENAME => array( 1, 'PAGENAME' ),
224 MAG_PAGENAMEE => array( 1, 'PAGENAMEE' ),
225 MAG_NAMESPACE => array( 1, 'NAMESPACE' ),
226 MAG_NAMESPACEE => array( 1, 'NAMESPACEE' ),
227 MAG_FULLPAGENAME => array( 1, 'FULLPAGENAME' ),
228 MAG_FULLPAGENAMEE => array( 1, 'FULLPAGENAMEE' ),
229 MAG_MSG => array( 0, 'MSG:' ),
230 MAG_SUBST => array( 0, 'SUBST:' ),
231 MAG_MSGNW => array( 0, 'MSGNW:' ),
232 MAG_END => array( 0, '__END__' ),
233 MAG_IMG_THUMBNAIL => array( 1, 'thumbnail', 'thumb' ),
234 MAG_IMG_MANUALTHUMB => array( 1, 'thumbnail=$1', 'thumb=$1'),
235 MAG_IMG_RIGHT => array( 1, 'right' ),
236 MAG_IMG_LEFT => array( 1, 'left' ),
237 MAG_IMG_NONE => array( 1, 'none' ),
238 MAG_IMG_WIDTH => array( 1, '$1px' ),
239 MAG_IMG_CENTER => array( 1, 'center', 'centre' ),
240 MAG_IMG_FRAMED => array( 1, 'framed', 'enframed', 'frame' ),
241 MAG_INT => array( 0, 'INT:' ),
242 MAG_SITENAME => array( 1, 'SITENAME' ),
243 MAG_NS => array( 0, 'NS:' ),
244 MAG_LOCALURL => array( 0, 'LOCALURL:' ),
245 MAG_LOCALURLE => array( 0, 'LOCALURLE:' ),
246 MAG_SERVER => array( 0, 'SERVER' ),
247 MAG_SERVERNAME => array( 0, 'SERVERNAME' ),
248 MAG_SCRIPTPATH => array( 0, 'SCRIPTPATH' ),
249 MAG_GRAMMAR => array( 0, 'GRAMMAR:' ),
250 MAG_NOTITLECONVERT => array( 0, '__NOTITLECONVERT__', '__NOTC__'),
251 MAG_NOCONTENTCONVERT => array( 0, '__NOCONTENTCONVERT__', '__NOCC__'),
252 MAG_CURRENTWEEK => array( 1, 'CURRENTWEEK' ),
253 MAG_CURRENTDOW => array( 1, 'CURRENTDOW' ),
254 MAG_REVISIONID => array( 1, 'REVISIONID' ),
255 MAG_PLURAL => array( 0, 'PLURAL:' ),
256 MAG_FULLURL => array( 0, 'FULLURL:' ),
257 MAG_FULLURLE => array( 0, 'FULLURLE:' ),
258 MAG_LCFIRST => array( 0, 'LCFIRST:' ),
259 MAG_UCFIRST => array( 0, 'UCFIRST:' ),
260 MAG_LC => array( 0, 'LC:' ),
261 MAG_UC => array( 0, 'UC:' ),
262 MAG_RAW => array( 0, 'RAW:' ),
263 );
264
265 if (!$wgCachedMessageArrays) {
266 require_once('Messages.php');
267 }
268
269 /* a fake language converter */
270 class fakeConverter {
271 var $mLang;
272 function fakeConverter($langobj) {$this->mLang = $langobj;}
273 function convert($t, $i) {return $t;}
274 function parserConvert($t, $p) {return $t;}
275 function getVariants() { return array( $this->mLang->getCode() ); }
276 function getPreferredVariant() {return $this->mLang->getCode(); }
277 function findVariantLink(&$l, &$n) {}
278 function getExtraHashOptions() {return '';}
279 function getParsedTitle() {return '';}
280 function markNoConversion($text) {return $text;}
281 function convertCategoryKey( $key ) {return $key; }
282
283 }
284
285 #--------------------------------------------------------------------------
286 # Internationalisation code
287 #--------------------------------------------------------------------------
288
289 class Language {
290 var $mConverter;
291 function Language() {
292
293 # Copies any missing values in the specified arrays from En to the current language
294 $fillin = array( 'wgSysopSpecialPages', 'wgValidSpecialPages', 'wgDeveloperSpecialPages' );
295 $name = get_class( $this );
296
297 if( strpos( $name, 'language' ) == 0){
298 $lang = ucfirst( substr( $name, 8 ) );
299 foreach( $fillin as $arrname ){
300 $langver = "{$arrname}{$lang}";
301 $enver = "{$arrname}En";
302 if( ! isset( $GLOBALS[$langver] ) || ! isset( $GLOBALS[$enver] ))
303 continue;
304 foreach($GLOBALS[$enver] as $spage => $text){
305 if( ! isset( $GLOBALS[$langver][$spage] ) )
306 $GLOBALS[$langver][$spage] = $text;
307 }
308 }
309 }
310 $this->mConverter = new fakeConverter($this);
311 }
312
313 /**
314 * Exports the default user options as defined in
315 * $wgDefaultUserOptionsEn, user preferences can override some of these
316 * depending on what's in (Local|Default)Settings.php and some defines.
317 *
318 * @return array
319 */
320 function getDefaultUserOptions() {
321 global $wgDefaultUserOptionsEn ;
322 return $wgDefaultUserOptionsEn ;
323 }
324
325 /**
326 * Exports $wgBookstoreListEn
327 * @return array
328 */
329 function getBookstoreList() {
330 global $wgBookstoreListEn ;
331 return $wgBookstoreListEn ;
332 }
333
334 /**
335 * @return array
336 */
337 function getNamespaces() {
338 global $wgNamespaceNamesEn;
339 return $wgNamespaceNamesEn;
340 }
341
342 /**
343 * A convenience function that returns the same thing as
344 * getNamespaces() except with the array values changed to ' '
345 * where it found '_', useful for producing output to be displayed
346 * e.g. in <select> forms.
347 *
348 * @return array
349 */
350 function getFormattedNamespaces() {
351 $ns = $this->getNamespaces();
352 foreach($ns as $k => $v) {
353 $ns[$k] = strtr($v, '_', ' ');
354 }
355 return $ns;
356 }
357
358 /**
359 * Get a namespace value by key
360 * <code>
361 * $mw_ns = $wgContLang->getNsText( NS_MEDIAWIKI );
362 * echo $mw_ns; // prints 'MediaWiki'
363 * </code>
364 *
365 * @param int $index the array key of the namespace to return
366 * @return mixed, string if the namespace value exists, otherwise false
367 */
368 function getNsText( $index ) {
369 $ns = $this->getNamespaces();
370 return isset( $ns[$index] ) ? $ns[$index] : false;
371 }
372
373 /**
374 * A convenience function that returns the same thing as
375 * getNsText() except with '_' changed to ' ', useful for
376 * producing output.
377 *
378 * @return array
379 */
380 function getFormattedNsText( $index ) {
381 $ns = $this->getNsText( $index );
382 return strtr($ns, '_', ' ');
383 }
384
385 /**
386 * Get a namespace key by value, case insensetive.
387 *
388 * @param string $text
389 * @return mixed An integer if $text is a valid value otherwise false
390 */
391 function getNsIndex( $text ) {
392 $ns = $this->getNamespaces();
393
394 foreach ( $ns as $i => $n ) {
395 if ( strcasecmp( $n, $text ) == 0)
396 return $i;
397 }
398 return false;
399 }
400
401 /**
402 * short names for language variants used for language conversion links.
403 *
404 * @param string $code
405 * @return string
406 */
407 function getVariantname( $code ) {
408 return wfMsg( "variantname-$code" );
409 }
410
411 function specialPage( $name ) {
412 return $this->getNsText(NS_SPECIAL) . ':' . $name;
413 }
414
415 function getQuickbarSettings() {
416 global $wgQuickbarSettingsEn;
417 return $wgQuickbarSettingsEn;
418 }
419
420 function getSkinNames() {
421 global $wgSkinNamesEn;
422 return $wgSkinNamesEn;
423 }
424
425 function getMathNames() {
426 global $wgMathNamesEn;
427 return $wgMathNamesEn;
428 }
429
430 function getDateFormats() {
431 global $wgDateFormatsEn;
432 return $wgDateFormatsEn;
433 }
434
435 function getUserToggles() {
436 global $wgUserTogglesEn;
437 return $wgUserTogglesEn;
438 }
439
440 function getUserToggle( $tog ) {
441 return wfMsg( "tog-$tog" );
442 }
443
444 function getLanguageNames() {
445 global $wgLanguageNamesEn;
446 return $wgLanguageNamesEn;
447 }
448
449 function getLanguageName( $code ) {
450 global $wgLanguageNamesEn;
451 if ( ! array_key_exists( $code, $wgLanguageNamesEn ) ) {
452 return '';
453 }
454 return $wgLanguageNamesEn[$code];
455 }
456
457 function getMonthName( $key ) {
458 global $wgMonthNamesEn, $wgContLang;
459 // see who called us and use the correct message function
460 if( get_class( $wgContLang->getLangObj() ) == get_class( $this ) )
461 return wfMsgForContent($wgMonthNamesEn[$key-1]);
462 else
463 return wfMsg($wgMonthNamesEn[$key-1]);
464 }
465
466 /* by default we just return base form */
467 function getMonthNameGen( $key ) {
468 return $this->getMonthName( $key );
469 }
470
471 function getMonthAbbreviation( $key ) {
472 global $wgMonthAbbreviationsEn, $wgContLang;
473 // see who called us and use the correct message function
474 if( get_class( $wgContLang->getLangObj() ) == get_class( $this ) )
475 return wfMsgForContent(@$wgMonthAbbreviationsEn[$key-1]);
476 else
477 return wfMsg(@$wgMonthAbbreviationsEn[$key-1]);
478 }
479
480 function getWeekdayName( $key ) {
481 global $wgWeekdayNamesEn, $wgContLang;
482 // see who called us and use the correct message function
483 if( get_class( $wgContLang->getLangObj() ) == get_class( $this ) )
484 return wfMsgForContent($wgWeekdayNamesEn[$key-1]);
485 else
486 return wfMsg($wgWeekdayNamesEn[$key-1]);
487 }
488
489 /**
490 * Used by date() and time() to adjust the time output.
491 * @access public
492 * @param int $ts the time in date('YmdHis') format
493 * @param mixed $tz adjust the time by this amount (default false)
494 * @return int
495
496 */
497 function userAdjust( $ts, $tz = false ) {
498 global $wgUser, $wgLocalTZoffset;
499
500 if (!$tz) {
501 $tz = $wgUser->getOption( 'timecorrection' );
502 }
503
504 if ( $tz === '' ) {
505 $hrDiff = isset( $wgLocalTZoffset ) ? $wgLocalTZoffset : 0;
506 $minDiff = 0;
507 } elseif ( strpos( $tz, ':' ) !== false ) {
508 $tzArray = explode( ':', $tz );
509 $hrDiff = intval($tzArray[0]);
510 $minDiff = intval($hrDiff < 0 ? -$tzArray[1] : $tzArray[1]);
511 } else {
512 $hrDiff = intval( $tz );
513 }
514 if ( 0 == $hrDiff && 0 == $minDiff ) { return $ts; }
515
516 $t = mktime( (
517 (int)substr( $ts, 8, 2) ) + $hrDiff, # Hours
518 (int)substr( $ts, 10, 2 ) + $minDiff, # Minutes
519 (int)substr( $ts, 12, 2 ), # Seconds
520 (int)substr( $ts, 4, 2 ), # Month
521 (int)substr( $ts, 6, 2 ), # Day
522 (int)substr( $ts, 0, 4 ) ); #Year
523 return date( 'YmdHis', $t );
524 }
525
526 /**
527 * This is meant to be used by time(), date(), and timeanddate() to get
528 * the date preference they're supposed to use, it should be used in
529 * all children.
530 *
531 *<code>
532 * function timeanddate([...], $format = true) {
533 * $datePreference = $this->dateFormat($format);
534 * [...]
535 *</code>
536 *
537 * @param mixed $usePrefs: if true, the user's preference is used
538 * if false, the site/language default is used
539 * if int/string, assumed to be a format.
540 * @return string
541 */
542 function dateFormat( $usePrefs = true ) {
543 global $wgUser;
544
545 if( is_bool( $usePrefs ) ) {
546 if( $usePrefs ) {
547 $datePreference = $wgUser->getOption( 'date' );
548 } else {
549 $options = $this->getDefaultUserOptions();
550 $datePreference = (string)$options['date'];
551 }
552 } else {
553 $datePreference = (string)$usePrefs;
554 }
555
556 // return int
557 if( $datePreference == '' ) {
558 return MW_DATE_DEFAULT;
559 }
560
561 return $datePreference;
562 }
563
564 /**
565 * @access public
566 * @param mixed $ts the time format which needs to be turned into a
567 * date('YmdHis') format with wfTimestamp(TS_MW,$ts)
568 * @param bool $adj whether to adjust the time output according to the
569 * user configured offset ($timecorrection)
570 * @param mixed $format true to use user's date format preference
571 * @param string $timecorrection the time offset as returned by
572 * validateTimeZone() in Special:Preferences
573 * @return string
574 */
575 function date( $ts, $adj = false, $format = true, $timecorrection = false ) {
576 global $wgUser, $wgAmericanDates;
577
578 if ( $adj ) { $ts = $this->userAdjust( $ts, $timecorrection ); }
579
580 $datePreference = $this->dateFormat( $format );
581 if( $datePreference == MW_DATE_DEFAULT ) {
582 $datePreference = $wgAmericanDates ? MW_DATE_MDY : MW_DATE_DMY;
583 }
584
585 $month = $this->formatMonth( substr( $ts, 4, 2 ), $datePreference );
586 $day = $this->formatDay( substr( $ts, 6, 2 ), $datePreference );
587 $year = $this->formatNum( substr( $ts, 0, 4 ), true );
588
589 switch( $datePreference ) {
590 case MW_DATE_DMY: return "$day $month $year";
591 case MW_DATE_YMD: return "$year $month $day";
592 case MW_DATE_ISO: return substr($ts, 0, 4). '-' . substr($ts, 4, 2). '-' .substr($ts, 6, 2);
593 default: return "$month $day, $year";
594 }
595 }
596
597 /**
598 * @access public
599 * @param mixed $ts the time format which needs to be turned into a
600 * date('YmdHis') format with wfTimestamp(TS_MW,$ts)
601 * @param bool $adj whether to adjust the time output according to the
602 * user configured offset ($timecorrection)
603 * @param mixed $format true to use user's date format preference
604 * @param string $timecorrection the time offset as returned by
605 * validateTimeZone() in Special:Preferences
606 * @return string
607 */
608 function time( $ts, $adj = false, $format = true, $timecorrection = false ) {
609 global $wgUser;
610
611 if ( $adj ) { $ts = $this->userAdjust( $ts, $timecorrection ); }
612 $datePreference = $this->dateFormat( $format );
613
614 $sep = ($datePreference == MW_DATE_ISO)
615 ? ':'
616 : $this->timeSeparator( $format );
617
618 $t = substr( $ts, 8, 2 ) . $sep . substr( $ts, 10, 2 );
619
620 if ( $datePreference == MW_DATE_ISO ) {
621 $t .= $sep . substr( $ts, 12, 2 );
622 }
623 return $t;
624 }
625
626 /**
627 * Default separator character between hours, minutes, and seconds.
628 * Will be used by Language::time() for non-ISO formats.
629 * (ISO will always use a colon.)
630 * @return string
631 */
632 function timeSeparator( $format ) {
633 return ':';
634 }
635
636 /**
637 * String to insert between the time and the date in a combined
638 * string. Should include any relevant whitespace.
639 * @return string
640 */
641 function timeDateSeparator( $format ) {
642 return ', ';
643 }
644
645 /**
646 * Return true if the time should display before the date.
647 * @return bool
648 * @access private
649 */
650 function timeBeforeDate() {
651 return true;
652 }
653
654 function formatMonth( $month, $format ) {
655 return $this->getMonthName( $month );
656 }
657
658 function formatDay( $day, $format ) {
659 return $this->formatNum( 0 + $day );
660 }
661
662 /**
663 * @access public
664 * @param mixed $ts the time format which needs to be turned into a
665 * date('YmdHis') format with wfTimestamp(TS_MW,$ts)
666 * @param bool $adj whether to adjust the time output according to the
667 * user configured offset ($timecorrection)
668
669 * @param mixed $format what format to return, if it's false output the
670 * default one (default true)
671 * @param string $timecorrection the time offset as returned by
672 * validateTimeZone() in Special:Preferences
673 * @return string
674 */
675 function timeanddate( $ts, $adj = false, $format = true, $timecorrection = false) {
676 global $wgUser;
677
678 $datePreference = $this->dateFormat($format);
679 switch ( $datePreference ) {
680 case MW_DATE_ISO: return $this->date( $ts, $adj, $format, $timecorrection ) . ' ' .
681 $this->time( $ts, $adj, $format, $timecorrection );
682 default:
683 $time = $this->time( $ts, $adj, $format, $timecorrection );
684 $sep = $this->timeDateSeparator( $datePreference );
685 $date = $this->date( $ts, $adj, $format, $timecorrection );
686 return $this->timeBeforeDate( $datePreference )
687 ? $time . $sep . $date
688 : $date . $sep . $time;
689 }
690 }
691
692 function getMessage( $key ) {
693 global $wgAllMessagesEn;
694 return @$wgAllMessagesEn[$key];
695 }
696
697 function getAllMessages() {
698 global $wgAllMessagesEn;
699 return $wgAllMessagesEn;
700 }
701
702 function iconv( $in, $out, $string ) {
703 # For most languages, this is a wrapper for iconv
704 return iconv( $in, $out, $string );
705 }
706
707 function ucfirst( $string ) {
708 # For most languages, this is a wrapper for ucfirst()
709 return ucfirst( $string );
710 }
711
712 function uc( $str ) {
713 return strtoupper( $str );
714 }
715
716 function lcfirst( $s ) {
717 return strtolower( $s{0} ). substr( $s, 1 );
718 }
719
720 function lc( $str ) {
721 return strtolower( $str );
722 }
723
724 function checkTitleEncoding( $s ) {
725 global $wgInputEncoding;
726
727 # Check for UTF-8 URLs; Internet Explorer produces these if you
728 # type non-ASCII chars in the URL bar or follow unescaped links.
729 $ishigh = preg_match( '/[\x80-\xff]/', $s);
730 $isutf = ($ishigh ? preg_match( '/^([\x00-\x7f]|[\xc0-\xdf][\x80-\xbf]|' .
731 '[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3})+$/', $s ) : true );
732
733 if( ($wgInputEncoding != 'utf-8') and $ishigh and $isutf )
734 return @iconv( 'UTF-8', $wgInputEncoding, $s );
735
736 if( ($wgInputEncoding == 'utf-8') and $ishigh and !$isutf )
737 return utf8_encode( $s );
738
739 # Other languages can safely leave this function, or replace
740 # it with one to detect and convert another legacy encoding.
741 return $s;
742 }
743
744 /**
745 * Some languages have special punctuation to strip out
746 * or characters which need to be converted for MySQL's
747 * indexing to grok it correctly. Make such changes here.
748 *
749 * @param string $in
750 * @return string
751 */
752 function stripForSearch( $in ) {
753 return strtolower( $in );
754 }
755
756 function convertForSearchResult( $termsArray ) {
757 # some languages, e.g. Chinese, need to do a conversion
758 # in order for search results to be displayed correctly
759 return $termsArray;
760 }
761
762 /**
763 * Get the first character of a string. In ASCII, return
764 * first byte of the string. UTF8 and others have to
765 * overload this.
766 *
767 * @param string $s
768 * @return string
769 */
770 function firstChar( $s ) {
771 return $s[0];
772 }
773
774 function initEncoding() {
775 # Some languages may have an alternate char encoding option
776 # (Esperanto X-coding, Japanese furigana conversion, etc)
777 # If this language is used as the primary content language,
778 # an override to the defaults can be set here on startup.
779 #global $wgInputEncoding, $wgOutputEncoding, $wgEditEncoding;
780 }
781
782 function setAltEncoding() {
783 # Some languages may have an alternate char encoding option
784 # (Esperanto X-coding, Japanese furigana conversion, etc)
785 # If 'altencoding' is checked in user prefs, this gives a
786 # chance to swap out the default encoding settings.
787 #global $wgInputEncoding, $wgOutputEncoding, $wgEditEncoding;
788 }
789
790 function recodeForEdit( $s ) {
791 # For some languages we'll want to explicitly specify
792 # which characters make it into the edit box raw
793 # or are converted in some way or another.
794 # Note that if wgOutputEncoding is different from
795 # wgInputEncoding, this text will be further converted
796 # to wgOutputEncoding.
797 global $wgInputEncoding, $wgEditEncoding;
798 if( $wgEditEncoding == '' or
799 $wgEditEncoding == $wgInputEncoding ) {
800 return $s;
801 } else {
802 return $this->iconv( $wgInputEncoding, $wgEditEncoding, $s );
803 }
804 }
805
806 function recodeInput( $s ) {
807 # Take the previous into account.
808 global $wgInputEncoding, $wgOutputEncoding, $wgEditEncoding;
809 if($wgEditEncoding != "") {
810 $enc = $wgEditEncoding;
811 } else {
812 $enc = $wgOutputEncoding;
813 }
814 if( $enc == $wgInputEncoding ) {
815 return $s;
816 } else {
817 return $this->iconv( $enc, $wgInputEncoding, $s );
818 }
819 }
820
821 /**
822 * For right-to-left language support
823 *
824 * @return bool
825 */
826 function isRTL() { return false; }
827
828 /**
829 * To allow "foo[[bar]]" to extend the link over the whole word "foobar"
830 *
831 * @return bool
832 */
833 function linkPrefixExtension() { return false; }
834
835
836 function &getMagicWords() {
837 global $wgMagicWordsEn;
838 return $wgMagicWordsEn;
839 }
840
841 # Fill a MagicWord object with data from here
842 function getMagic( &$mw ) {
843 $raw = $this->getMagicWords();
844
845 wfRunHooks( 'LanguageGetMagic', array( &$raw ) );
846
847 if( !isset( $raw[$mw->mId] ) ) {
848 # Fall back to English if local list is incomplete
849 $raw =& Language::getMagicWords();
850 }
851 $rawEntry = $raw[$mw->mId];
852 $mw->mCaseSensitive = $rawEntry[0];
853 $mw->mSynonyms = array_slice( $rawEntry, 1 );
854 }
855
856 /**
857 * Italic is unsuitable for some languages
858 *
859 * @access public
860 *
861 * @param string $text The text to be emphasized.
862 * @return string
863 */
864 function emphasize( $text ) {
865 return "<em>$text</em>";
866 }
867
868 /**
869 * This function enables formatting of numbers, it should only come
870 * into effect when the $wgTranslateNumerals variable is TRUE.
871 *
872 * Normally we output all numbers in plain en_US style, that is
873 * 293,291.235 for twohundredninetythreethousand-twohundredninetyone
874 * point twohundredthirtyfive. However this is not sutable for all
875 * languages, some such as Pakaran want ੨੯੩,੨੯੫.੨੩੫ and others such as
876 * Icelandic just want to use commas instead of dots, and dots instead
877 * of commas like "293.291,235".
878 *
879 * An example of this function being called:
880 * <code>
881 * wfMsg( 'message', $wgLang->formatNum( $num ) )
882 * </code>
883 *
884 * See LanguageGu.php for the Gujarati implementation and
885 * LanguageIs.php for the , => . and . => , implementation.
886 *
887 * @todo check if it's viable to use localeconv() for the decimal
888 * seperator thing.
889 * @access public
890 * @param mixed $number the string to be formatted, should be an integer or
891 * a floating point number.
892 * @param bool $year are we being passed a year? (turns off commafication)
893 * @return mixed whatever we're fed if it's a year, a string otherwise.
894 */
895 function formatNum( $number, $year = false ) {
896 return $year ? $number : $this->commafy($number);
897 }
898
899 /**
900 * Adds commas to a given number
901 *
902 * @param mixed $_
903 * @return string
904 */
905 function commafy($_) {
906 return strrev((string)preg_replace('/(\d{3})(?=\d)(?!\d*\.)/','$1,',strrev($_)));
907 }
908
909 /**
910 * For the credit list in includes/Credits.php (action=credits)
911 *
912 * @param array $l
913 * @return string
914 */
915 function listToText( $l ) {
916 $s = '';
917 $m = count($l) - 1;
918 for ($i = $m; $i >= 0; $i--) {
919 if ($i == $m) {
920 $s = $l[$i];
921 } else if ($i == $m - 1) {
922 $s = $l[$i] . ' ' . wfMsg('and') . ' ' . $s;
923 } else {
924 $s = $l[$i] . ', ' . $s;
925 }
926 }
927 return $s;
928 }
929
930 # Crop a string from the beginning or end to a certain number of bytes.
931 # (Bytes are used because our storage has limited byte lengths for some
932 # columns in the database.) Multibyte charsets will need to make sure that
933 # only whole characters are included!
934 #
935 # $length does not include the optional ellipsis.
936 # If $length is negative, snip from the beginning
937 function truncate( $string, $length, $ellipsis = '' ) {
938 if( $length == 0 ) {
939 return $ellipsis;
940 }
941 if ( strlen( $string ) <= abs( $length ) ) {
942 return $string;
943 }
944 if( $length > 0 ) {
945 $string = substr( $string, 0, $length );
946 return $string . $ellipsis;
947 } else {
948 $string = substr( $string, $length );
949 return $ellipsis . $string;
950 }
951 }
952
953 /**
954 * Grammatical transformations, needed for inflected languages
955 * Invoked by putting {{grammar:case|word}} in a message
956 *
957 * @param string $word
958 * @param string $case
959 * @return string
960 */
961 function convertGrammar( $word, $case ) {
962 return $word;
963 }
964
965 /**
966 * Plural form transformations, needed for some languages.
967 * For example, where are 3 form of plural in Russian and Polish,
968 * depending on "count mod 10". See [[w:Plural]]
969 * For English it is pretty simple.
970 *
971 * Invoked by putting {{plural:count|wordform1|wordform2}}
972 * or {{plural:count|wordform1|wordform2|wordform3}}
973 *
974 * Example: {{plural:{{NUMBEROFARTICLES}}|article|articles}}
975 *
976 * @param integer $count
977 * @param string $wordform1
978 * @param string $wordform2
979 * @param string $wordform3 (optional)
980 * @return string
981 */
982 function convertPlural( $count, $wordform1, $wordform2, $wordform3) {
983 return $count == '1' ? $wordform1 : $wordform2;
984 }
985
986 /**
987 * For translaing of expiry times
988 * @param string The validated block time in English
989 * @return Somehow translated block time
990 * @see LanguageFi.php for example implementation
991 */
992 function translateBlockExpiry( $str ) {
993
994 $scBlockExpiryOptions = wfMsg( 'ipboptions' );
995
996 if ( $scBlockExpiryOptions == '-') {
997 return $str;
998 }
999
1000 foreach (explode(',', $scBlockExpiryOptions) as $option) {
1001 if ( strpos($option, ":") === false )
1002 continue;
1003 list($show, $value) = explode(":", $option);
1004 if ( strcmp ( $str, $value) == 0 )
1005 return '<span title="' . htmlspecialchars($str). '">' .
1006 htmlspecialchars( trim( $show ) ) . '</span>';
1007 }
1008
1009 return $str;
1010 }
1011
1012 /**
1013 * languages like Chinese need to be segmented in order for the diff
1014 * to be of any use
1015 *
1016 * @param string $text
1017 * @return string
1018 */
1019 function segmentForDiff( $text ) {
1020 return $text;
1021 }
1022
1023 /**
1024 * and unsegment to show the result
1025 *
1026 * @param string $text
1027 * @return string
1028 */
1029 function unsegmentForDiff( $text ) {
1030 return $text;
1031 }
1032
1033 # convert text to different variants of a language.
1034 function convert( $text, $isTitle = false) {
1035 return $this->mConverter->convert($text, $isTitle);
1036 }
1037
1038 # Convert text from within Parser
1039 function parserConvert( $text, &$parser ) {
1040 return $this->mConverter->parserConvert( $text, $parser );
1041 }
1042
1043 /**
1044 * Perform output conversion on a string, and encode for safe HTML output.
1045 * @param string $text
1046 * @param bool $isTitle -- wtf?
1047 * @return string
1048 * @todo this should get integrated somewhere sane
1049 */
1050 function convertHtml( $text, $isTitle = false ) {
1051 return htmlspecialchars( $this->convert( $text, $isTitle ) );
1052 }
1053
1054 function convertCategoryKey( $key ) {
1055 return $this->mConverter->convertCategoryKey( $key );
1056 }
1057
1058 /**
1059 * get the list of variants supported by this langauge
1060 * see sample implementation in LanguageZh.php
1061 *
1062 * @return array an array of language codes
1063 */
1064 function getVariants() {
1065 return $this->mConverter->getVariants();
1066 }
1067
1068
1069 function getPreferredVariant() {
1070 return $this->mConverter->getPreferredVariant();
1071 }
1072
1073 /**
1074 * if a language supports multiple variants, it is
1075 * possible that non-existing link in one variant
1076 * actually exists in another variant. this function
1077 * tries to find it. See e.g. LanguageZh.php
1078 *
1079 * @param string $link the name of the link
1080 * @param mixed $nt the title object of the link
1081 * @return null the input parameters may be modified upon return
1082 */
1083 function findVariantLink( &$link, &$nt ) {
1084 $this->mConverter->findVariantLink($link, $nt);
1085 }
1086
1087 /**
1088 * returns language specific options used by User::getPageRenderHash()
1089 * for example, the preferred language variant
1090 *
1091 * @return string
1092 * @access public
1093 */
1094 function getExtraHashOptions() {
1095 return $this->mConverter->getExtraHashOptions();
1096 }
1097
1098 /**
1099 * for languages that support multiple variants, the title of an
1100 * article may be displayed differently in different variants. this
1101 * function returns the apporiate title defined in the body of the article.
1102 *
1103 * @return string
1104 */
1105 function getParsedTitle() {
1106 return $this->mConverter->getParsedTitle();
1107 }
1108
1109 /**
1110 * Enclose a string with the "no conversion" tag. This is used by
1111 * various functions in the Parser
1112 *
1113 * @param string $text text to be tagged for no conversion
1114 * @return string the tagged text
1115 */
1116 function markNoConversion( $text ) {
1117 return $this->mConverter->markNoConversion( $text );
1118 }
1119
1120 /**
1121 * A regular expression to match legal word-trailing characters
1122 * which should be merged onto a link of the form [[foo]]bar.
1123 *
1124 * @return string
1125 * @access public
1126 */
1127 function linkTrail() {
1128 return $this->getMessage( 'linktrail' );
1129 }
1130
1131 function getLangObj() {
1132 return $this;
1133 }
1134
1135 /**
1136 * Get the RFC 3066 code for this language object
1137 */
1138 function getCode() {
1139 return str_replace( '_', '-', strtolower( substr( get_class( $this ), 8 ) ) );
1140 }
1141
1142
1143 }
1144
1145 # FIXME: Merge all UTF-8 support code into Language base class.
1146 # We no longer support Latin-1 charset.
1147 require_once( 'LanguageUtf8.php' );
1148
1149 # This should fail gracefully if there's not a localization available
1150 wfSuppressWarnings();
1151 // Preload base classes to work around APC/PHP5 bug
1152 include_once( 'Language' . str_replace( '-', '_', ucfirst( $wgLanguageCode ) ) . '.deps.php' );
1153 include_once( 'Language' . str_replace( '-', '_', ucfirst( $wgLanguageCode ) ) . '.php' );
1154 wfRestoreWarnings();
1155
1156 }
1157 ?>